package com.yeyks.account.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeyks.account.dal.dao.SysUserRoleMapper;
import com.yeyks.account.dal.domain.SysAppMenu;
import com.yeyks.account.dal.dao.SysAppMenuMapper;
import com.yeyks.account.service.SysAppMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yeyks.common.appcommon.dto.AppRouteDTO;
import com.yeyks.common.utils.apputil.redis.RedisService;
import com.yeyks.common.utils.apputil.rediskey.RedisKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;


/**
 * <p>
 * 菜单管理 服务实现类
 * </p>
 *
 * @author yun
 * @since 2019-06-25
 */
@Service
public class SysAppMenuServiceImpl extends ServiceImpl<SysAppMenuMapper, SysAppMenu> implements SysAppMenuService {

    private SysAppMenuMapper sysAppMenuMapper;

    private SysUserRoleMapper sysUserRoleMapper;

    private RedisService redisService;

    @Autowired
    public SysAppMenuServiceImpl(
            SysAppMenuMapper sysAppMenuMapper,
            SysUserRoleMapper sysUserRoleMapper,
            RedisService redisService) {
        this.sysAppMenuMapper = sysAppMenuMapper;
        this.sysUserRoleMapper = sysUserRoleMapper;
        this.redisService = redisService;
    }

    @Override
    public List<AppRouteDTO> selectByAccountId(Long accountId) {
        List<AppRouteDTO> appRouteDTOList = Lists.newArrayList();

        List<Long> roleIds = sysUserRoleMapper.queryRoleIdList(accountId);

        //根据角色Ids查询菜单集合
        List<SysAppMenu> appSysAppMenuList = sysAppMenuMapper.selectMenuByRoleIds(roleIds);

        //循环遍历组装
        if (!CollectionUtils.isEmpty(appSysAppMenuList)) {
            appRouteDTOList = convertSysAppMenu(appSysAppMenuList);
            //将路由信息存入缓存（保持最新）
            redisService.set(RedisKey.getRoleRouteKey(String.valueOf(accountId)), JSONObject.toJSONString(appSysAppMenuList));
        }
        return appRouteDTOList;
    }

    @Override
    public boolean checkUpdate(Long accountId) {
        String json = redisService.get(RedisKey.getRoleRouteKey(String.valueOf(accountId)));
        if(!StringUtils.isEmpty(json)){
            //取到old的路由权限
            List<SysAppMenu> appRouteDTOList = JSONObject.parseArray(json,SysAppMenu.class);

            //获取最新的菜单ID集合
            List<Long> menuIds = sysAppMenuMapper.selectMenuIdByAccountId(accountId);


            //判断的逻辑， 判断old中的所有的MenuId 是否在 new中的集合
            //1.如果数量大小不同，返回true
            if(appRouteDTOList.size() != menuIds.size()){
                return true;
            }
            //2.如果内容不一致，返回true
            for(SysAppMenu appRouteDTO : appRouteDTOList){
                if(!menuIds.contains(appRouteDTO.getMenuId())){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 树形数组装
     *
     * @param appSysAppMenuList 角色菜单数据
     * @return 返回结果
     */
    private List<AppRouteDTO> convertSysAppMenu(List<SysAppMenu> appSysAppMenuList) {

        List<AppRouteDTO> appRouteDTOList = Lists.newArrayList();

        for(SysAppMenu sysAppMenu : appSysAppMenuList){
            AppRouteDTO appRouteDTO = new AppRouteDTO();
            appRouteDTO.setRouteName(sysAppMenu.getName());
            appRouteDTO.setRouteUrl(sysAppMenu.getUrl());
            appRouteDTO.setRouteImg(sysAppMenu.getIcon());
            appRouteDTO.setRouteId(sysAppMenu.getMenuId());
            appRouteDTO.setRouteParentId(sysAppMenu.getParentId());
            appRouteDTO.setRouteSort(sysAppMenu.getOrderNum());
            appRouteDTOList.add(appRouteDTO);
        }

        return toTreeList(appRouteDTOList);
    }

    /**
     * 改造树形
     * @param routeList 路由集合
     * @return 返回组装后的数据
     */
    private List<AppRouteDTO> toTreeList(List<AppRouteDTO> routeList) {
        Map<Object, AppRouteDTO> maps = Maps.newHashMap();
        List<AppRouteDTO> list = Lists.newArrayList();
        for (AppRouteDTO routeDTO : routeList) {
            addTreeNode(routeDTO, maps, list);
        }
        return list;
    }

    /**
     * 构建属性节点
     * @param routeDTO 当前路由对象
     * @param maps 存入路由对象的空Map
     * @param list 存入子对象的集合
     */
    private void addTreeNode(AppRouteDTO routeDTO, Map<Object, AppRouteDTO> maps,
                             List<AppRouteDTO> list) {
        if(maps.containsKey(routeDTO.getRouteId())){
            maps.get(routeDTO.getRouteId()).setEntity(routeDTO);
        }else{
            maps.put(routeDTO.getRouteId(), routeDTO);
        }
        if(routeDTO.getRouteParentId() == null || routeDTO.getRouteParentId() == 0L){
            list.add(maps.get(routeDTO.getRouteId()));
        }else{
            if(maps.containsKey(routeDTO.getRouteParentId())){
                maps.get(routeDTO.getRouteParentId()).addChildren(routeDTO);
            }else{
                AppRouteDTO parent = new AppRouteDTO();
                parent.addChildren(routeDTO);
                maps.put(routeDTO.getRouteParentId(),parent);
            }
        }
    }
}
